这是个 windows 的靶场:
一开始常规的 nmap 扫描
发现 88 端口开放,这很可能是个 kdc 兼 domain 的靶机,同时开放了 ldap,smb 服务。
在机器的描述中给出了一个用户的账户密码 P.Rosa / Rosaisbest123
尝试用 nxc 登录:
登录出错,但是可以看到 domain 是 vintage.htb
Google 发现这个错误可能是 kdc 禁用了 NTLM 认证,这个是 nxc 的默认认证方式,实际上
windows server 的默认认证方式是 Kerberos,只有启用了 protocol transition 才能用 NTML 访
问需要 Kerberos 认证的服务,其中用到了委派机制,后面会展开讲讲。这也暗示了 protocol
Transition 是关闭的。
尝试用 Kerberos 认证:
已经登录成功
接下来是信息收集的环节
先在/etc/hosts 中添加 dc01.vintage.htb,
然后 ldap 查询所有用户:
这里有几个很有趣的用户:xxxx$,svc_xxx,gMSA01$,还有 xxxx_adm,一个个来看看这些用户的
组和 description:
DC01$:
DC01 是 domain controller
FS01$:
fs 是 pre2000 用户,是在 windows2000 中预设的用户,意味着它的默认密码很可能是小写的
用户名 fs01:
尝试登录就会发现确实是这样,这个账户是属于 computers CN,可以任意修改自己的 ACL
或者创建新的 computer,目前不知道是否有用。
用户名 svcxxx 属于 serviceaccounts,用户 gmsa01 属于 Managed Service Accounts,C.Neri 属于
serviceaccountmanager,xxx_adm 属于 delegated admins
接下来需要了解一下这些用户和组之间的权限关系:
Servicemanager 对 serviceaccount 具有大部分权限,以 svc_sql 为例:
查看 delegated_admins 的 ACE:
Xxxx_adm 对这个 group 具有写属性的权限
然后权限的事情暂时先放一边
先看看对哪些用户有控制,目前有 fs01,P.Rosa,我们可以尝试去搜索一下有没有可以读取的
密码:
基于 fs01 具有稍微高一点的权限,用 fs01 账号来搜索 msds-managedpassword 属性:
确实找到了,去掉 grep 不难发现这是 gmsa01 的 ntlm HASH,那么我们可以 pass the ticket
来获取 GMSA01 的 TGT,GMSA01 就是 servieaccountmanager
现在的信息是否足以构成攻击链呢?
首先,protocol transition(PT)是关闭的,因此 S4U2self 永远返回的是没有 forwardable flag 的
ST,几个著名的攻击方法
(ref https://www.thehacker.recipes/ad/movement/kerberos/delegations/constrained)
中比较有可行性的是 KCD 和 RBCD ABUSE,因为 KUD 需要等待高权限用户主动访问 service,
但是高权限用户我们目前一个都没有,最高权限的就是 GMSA01 了,
因此不考虑。KCD 需要 msDS-AllowedToDelegateTo 被设置为需要访问的 service(通常是高权
限用户的 SPN),但是:
这是未配置的,还剩下一种 RBCD ABUSE,是否可行?
先看这张攻击流程图

前置知识:
--------------------------------------------------------
S4U2self:任意服务(具有 spn)都可以随时向 kdc 发起 S4U2self 请求,这种请求的含义是
“我想代表某个用户访问自己”,无论 TrustedToAuthForDelegation,UserAccountControl flag
是否被设置,但是,如果 PT 未对该用户开启,或者上面提到的两个属性未被设置,这个请
求的响应(含有对目标服务的 ST)不会含有 forwardable flag,也就是说这个 ST 在之后的
S4U2proxy 是无用的(kdc 不会返回有效的 ST)。(forwardable flag 决定目标服务是否接受这个
ST)
S4U2proxy:这个请求需要一个 service 持有一个具有 forwardable flag 的 ST(通常是通过
S4U2self 获得的),kdc 会返回一个 ST,允许这个服务以之前的 ST 中它代表的用户访问其它
服务,换句话说,假设有 admin,S1(service),S2(特权服务),那么在 S1 开启了 PT,设置了
相应的属性的时候,S1 向 kdc 请求 ST(admin->s1) (这就是 S4U2self),接着,S1 向 kdc 请求
ST(admin->s2),带上之前的 ST(admin->s1)作为 addition ST,验证成功 kdc(需要 forwardable
设置,还需要 S1 被设置了 allowtodelegateto)会返回一个 ST(admin->s2)(这就是 s4u2proxy,
proxy 就是 s2),最后 s1 可以在不知道 admin 密码的情况下获得特权去访问 s2
---------------------------------------------------------
RBCD abuse 攻击的原理:,S4U2proxy 本来需要 forwardable 设置,还需要
S1 被设置了 allowtodelegateto,但是 ms2012 之后出现了一种叫做 RBCD 的功能,只要 s2 设
置了 msDS-AllowedToActOnBehalfOfOtherIdentity 属性,值为 s1 的 nt-sec-desc,(有特定的
格式,其中含有 s1 的 sid),那么如果 s1 在向 kdc 的 s4u2proxy 请求中带上了 rbcd bit,那么
无论是否有 forwardable 或者 s1 有没有 allowtodelegateto,kdc 会接受 s4u2self 的 st,并且返
回一个 forwardable 的 st 用于访问 s2。注意:
1. s1 不会自己发送带上 rbcd bit 的请求,因此,攻击者需要有控制 s1 账户的能力,用 impacket
的 getST 的时候,这个 bit 会被自动设置 RBCD_ABUSE
2. 向 kdc 请求成功的 s4u2proxy 请求总是返回 forwardable 的 st
(https://eladshamir.com/2019/01/28/Wagging-the-Dog.html#serendipity)
尝试找一下哪个用户设置了这个,确实可以找到:
一个是 fs01 的(应该是别人设置的,当然自己也可以设置),一个是 dc01 的
看看 dc01 的指向哪个对象:
是 delegatedadmins,也就是说,如果能够控制一个 delegatedadmin,我们可以直接获得最高
权限。
现在尝试用 smb 能不能读 C$:
不但不能读,其它文件夹也没有什么有用的文件
常规思路都不行,那么试试爆破吧,直接爆破肯定是不行的,用户很多,而且认证速度奇慢,
存在一种叫做 ASREPROAST 的方法,这种方法的原理是,对于可以在 object 的 uac 对象设置
DONT_REQ_PREAUTH 位的账户(0x400000),在向服务器发起 AS_REQ 的时候服务器不会验证是
否提供了正确的密码或者凭证,如果服务器支持 RC4 加密(在 as_req 指定),那么服务器会
用 NT HASH 加密一个 nonce 发回来。如图:
这个 user hash 就可以离线爆破,用 hashcat 或者 jonh the ripper,字典通常用 rockyou.txt
我们的目标是找到可以设置 DONT_REQ_PREAUTH 的账户,换句话说,要有某个账户,对一
组 账 户 具 有 write 权 限 , 这 个 账 户 目 前 只 能 是 GMSA01 , 就 像 一 开 始 说 的
serviceaccountmanager 对 service account 具有写权限,serviceaccount 以 svc 开头,而 gmsa01
可以把用户移动到非特权组,因此我们要把一个用户移动到 serviceaccountmanager 下,然后
以对应用户的身份对这些 serviceaccount 设置相应 flag,这可以用 bloodyAD 来完成。
先获得 GMSA01$的 TGT:
设置环境变量:
测试的时候发现 GMSA 自己移动到 serviceaccountmanager 组貌似不会继承这个组的权限,
但是用 P.Rosa 或者 fs01 都可以:
导出 userlist:
前面几行不管了,手动删除也可以,其实这里有几个用户没显示出来,比如 fs01,但是不重
要了,主要是 svc_开头的
使用 netexec 去获得 asreproast 中用 NTLM hash 加密的部分,后续用 jonh the ripper 去爆破
这里不用指定-k,当然指定也可以,你会发现 svc_sql 不见了,其实是这个账户被禁用了:
’
userAccountControl: 4260354 的 hex 是 0x410202
这里就可以看出来了,问题不大,我们权限足够,启用就可以:
动作要快,靶机有自动重置权限的脚本,一段时间就会自动运行一次:
然后把流程重新走一遍就正常了:
结果:
这个账户的密码是得到了,但是它只是一个 serviceaccount,rbcd abuse 要求有一个被特权服
务的 msds-allowedtoactonbehalfofotherentity 指定的服务,所以还是不满足要求,不过,我
们可以用 user.txt 去试一下有没有其它用户和它密码是一样的,P.Rosa 和 fs01 也可以一起试
试,最终会发现 C.Neri 也是这个密码,这个技巧其实在 htb 是挺常见的
那么得到 C.Neri / Zer0the0ne,这个用户有什么用?看看:
Remote managerment user,也就是可以远程登录 ps,我们用 winrm 试试:
不要用 impacket 的 psexxec 或者 winrmexec,它们会自动连接 smb,会有权限问题
接下来尝试权限提升
你会发现所有上传的可执行文件似乎都被禁用了,实际上靶机是有杀软的(没去试免杀,但
是免杀也难提权啊)。
执行 whoami /priv 你会发现这是个低权限用户,但是翻一下 C.Neri 用户的文件夹会发现
roaming 下有东西的:
Windows 下有一个机制,我们经常看见浏览器自动填写账户密码,实际上它们被用用户的
RSA keys 加密后存放在 credentials 目录下,而这些 RSA keys 被放在 protected 目录下的{sid},
这个文件中除了加密的 RSA KEYS,还会有一个加密过的叫 master key 的对称密钥,可以解密
RSA 的私钥,因此,对 protected 目录有访问权限,并且有登录密码,意味着可以解密一些
敏感数据:
其中就可能包括其它用户的远程登录密码
( https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/dpapi-extr
acting-passwords)
我们来尝试获取一下用户的私钥
直接用 download 会出现 IOT 错误,用 base64 编码后复制到本地:
导出密码:
看看 credentials 目录的内容:
不知道哪个主密钥是被用来加密它的,都试一下就好:
于是又得到了一个用户的密码,这个用户不是远程登录用户(远程登录用户必须是 remote
manager 组,local admins,domain admins 其中之一),因此没法 evil-winrm
之前提到过 delegatedadmins 和 dc01 的关系,delegatedadmins 可以代表任何账户去访问 dc01
的 所 有 服 务 , 只 要 用 RBCD ABUSE 就 可 以 了 , 但 是 delegatedadmins 本 身 必 须 有 SPN
(serviePrincipleName),不然 kdc 会报错,C.Neri_adm 本身是没有这个属性的(见上图),因
此我们需要想办法添加这个属性,一但添加了这个属性,我们就有办法用控制的账户去访问
DC01 的服务,由于 DC01 是 domain controller,这个靶机是单域的,因此就可以访问所有域
上的服务,当然,这并不能直接拿到 root 权限,但是可以访问 DC01 的 CIFS,这是 smb 的早
期版本,我们可以用 root 的访问权限去读取 c$中的 root.txt(执行不了 powershell,相当于
是获得了在 smb 中活动的最高权限)。
但是,尝试给 C.Neri_adm 自己添加 SPN 会失败:
C.Neri_adm 对自己只有有 read 权限:
SPN 的访问控制是更加精细的,添加 spn 需要 validate-spn,比如 fs 就有(computer 组都有这
个权限):
或者,有 self:
实际上,之前提到过,servicemanagers 对 serviceaccount 有高权限,其中就包括 self(其实
是 genericall 包括了这个 self):
现在有点尴尬了,有 delegate flag 的用户没有 SPN,能添加 SPN 的用户不在 delegatedadmins
当中。
但是,我们可以用 C.Neri 对 serviceaccount 添加 SPN(随便叫什么),然后用 C.Neri_adm 移
动 到 delegated admins 组 , 这 样 就 可 以 用 这 个 serviceaccount 实 现 RBCD ABUSE( 这 个
serviceaccount 应该要是 svc_sql,因为我们只知道它的密码):
防止之前启用的 svc_sql 被重置:
拿个 TGT(可以跳过这步,但是后面得输入密码):
我们要代表谁去访问 dc01 的 cifs 呢?
当然要是高权限用户,administrator,dc01,L.Bianchi_adm(domainadmin)之一,以 administrator
为例:
上图中 getST 部分就是 s4u2self+s4u2proxy 的集成操作。获取 ST 后,可以访问 cifs 服务(注
意,只能访问 cifs 服务,这是 st 和 TGT 的区别)。Cifs 是基于 smb,我们可以用 smb 来在 C$读
取 root.txt,但是上面的读取失败了,因为 administrator 是被禁止访问 cifs 的,DC01 也是一样
的,但是 L.Bianchi_adm 可以:
事实上不止可以读取文件,Smbexec 还能用 smb 来实现远程的 cmd.exe 执行,我想说的是为
什么 cifs 通过 smb 文件传输能够实现命令执行:
原理是 Smbexec 通过 smb 的$IP 管道向远程 windows 服务器上注册服务,这个服务启动后会
监听我们机器发送的指令并且用 cmd.exe 执行,然后把结果放在 c:\__output,smbexec 会读
取并且显示结果,就像打开了远程 shell 一样,结束会话后这个文件会被删掉
(https://www.cybertriage.com/blog/dfir-breakdown-impacket-remote-execution-activity-smbexe
c/)
这个靶机 smb 足够了
后来发现信息搜集直接
bloodhound-python --zip -u P.Rosa -p 'Rosaisbest123' -d vintage.htb -c All -dc dc01.vintage.htb
就好..................
Asreproast 一眼就看出来了...,省了前面很多分析的时间
你也会看到 L.Bianchi_adm 有 dcsync 的权限,但是没什么用,你只有 L.Bianchi_adm 对 cifs
的 ST,访问不了 RPC 的。